Podsumowanie analizy

Raport przedstawia analizę danych dotyczących materiałów stosowanych w bateriach, uwzględniając ich właściwości chemiczne i fizyczne. Dane są kompletne, a metody przetwarzania umożliwiły usunięcie wartości odstających, co poprawiło jakość analizy. Kluczowe obserwacje obejmują:
  • Większość baterii opiera się na Li jako głównym jonie. Natomiast jony, które znajdują się blisko Li w układzie okresowym są następnymi po popularności - Na, Mg i Ca.
  • Większość baterii charakteryzuje się stabilnym średnim (3-4 V) napięciem, umiarkowaną pojemnością wolumetryczną i grawimetryczną oraz stosunkowo niskimi wskaźnikami zmiany objętości dla danego kroku napięcia.
  • Materiał baterii w stanie naładowanym najczęściej jest w postaci tlenku.
  • Zdecydowana większość baterii ma udział atomowy składników w stanie naładowanym równy się 0.
  • Większość baterii potrzebuje 1 lub 2 kroki napięcia od naładowania do rozładowania.
  • Istnieją silne korelacje między parametrami opisującymi pojemność, energię i liczbę kroków napięcia.

Model stworzony do predykcji pojemności baterii, która jest jedną z najważniejszych właściwości, pokazuje, że udział atomowy składników w stanie rozładowanym wpływa na przewidywanie pojemności grawimetrycznej.

Wykorzystane biblioteki

W raporcie wykorzystano następujące biblioteki:

# do napisania raportu
library(knitr)

# do pracy z data.frame
library(dplyr)

# do budowanie modelu
library(caret)
library(xgboost)
library(Metrics)

# do równoległego wykonania
library(doParallel)

# do wizualizacji
library(ggplot2)
library(plotly)
library(ggcorrplot)
library(RColorBrewer)
library(kableExtra)
library(DT)

Powtarzalność wyników

Powtarzalność wyników jest zapewniona ustawieniem seed.

set.seed(7)

Wczytanie danych o bateriach z pliku

Do wczytania danych z pliku .csv użyto funckji read.csv. Najpierw wczytano 100 wierszy, ustalono ich typ i użyto tej informacji do wczytania już całego zbioru danych.

initial <- read.csv("mp_batteries.csv", nrows = 100)
classes <- sapply(initial, class)
df <- read.csv("mp_batteries.csv",
                     colClasses = classes)
Pierwsze 10 wierszy wczytanych danych wyglądają w następujący sposób:
Battery.ID Battery.Formula Working.Ion Formula.Charge Formula.Discharge Max.Delta.Volume Average.Voltage Gravimetric.Capacity Volumetric.Capacity Gravimetric.Energy Volumetric.Energy Atomic.Fraction.Charge Atomic.Fraction.Discharge Stability.Charge Stability.Discharge Steps Max.Voltage.Step
mp-30_Al Al0-2Cu Al Cu Al2Cu 3.0433992 0.0890331 1368.48055 5562.7901 121.840086 495.272533 0.0000000 0.6666667 0.0000000 0.0000000 1 0
mp-1022721_Al Al1-3Cu Al AlCu Al3Cu 1.2436528 -0.0215863 1112.93655 4418.9798 -24.024232 -95.389622 0.5000000 0.7500000 0.0740612 0.0962458 1 0
mp-8637_Al Al0-5Mo Al Mo Al5Mo 4.7625743 0.1227568 1741.50416 7175.7017 213.781556 880.866507 0.0000000 0.8333333 0.4114601 0.0452120 1 0
mp-129_Al Al0-12Mo Al Mo Al12Mo 12.7238931 0.0431214 2298.81076 7346.2323 99.128013 316.780060 0.0000000 0.9230769 0.0000000 0.0114456 1 0
mp-91_Al Al0-12W Al W Al12W 12.4945977 0.0292342 1900.74513 7332.7186 55.566774 214.366205 0.0000000 0.9230769 0.0000000 0.0000000 1 0
mp-1055908_Al Al0-12Mn Al Mn MnAl12 18.2361563 0.0397314 2547.69280 7592.9161 101.223298 301.676876 0.0000000 0.9230769 0.1454643 0.0000000 1 0
mp-2658_Al Al0-1Fe Al Fe AlFe 0.7711539 0.4717287 970.75702 5622.3562 457.933974 2652.226958 0.0000000 0.5000000 0.7613994 0.0000000 1 0
mp-16722_Al Al1-10.25V Al Al10V Al41V4 0.0027108 -0.0155827 61.37701 176.4151 -0.956421 -2.749028 0.9090909 0.9111111 0.0118097 0.0125861 1 0
mp-998981_Al Al1-3Ti Al TiAl TiAl3 0.9562924 0.1602450 1248.40362 4248.4211 200.050419 680.788169 0.5000000 0.7500000 0.1415912 0.0244962 1 0
mp-8633_K K0-3Cr K Cr K3Cr 15.8029363 -0.7487069 474.94813 667.5593 -355.596958 -499.806269 0.0000000 0.7500000 0.4025263 0.6621618 1 0

Przetwarzanie brakujących danych

Wykorzystano funckje complete.cases, która zwraca “1” dla wierszy “pełnych” tzn. które nie zawierają NA. Porównano sumę “1” z liczbą wierszy w zbiorze danych i te liczbe są takie same. To oznacza, że w zbiorze nie ma wartosci brakujących.

complete_rows <- sum(complete.cases(df))
rows_with_NA <- nrow(df) - complete_rows
rows_with_NA
## [1] 0

Podstawowe statystyki zbióru danych

Zbiór danych składa się z 4351 wierszy i 17 atrybutów. Poniżej przedstawione podstawowe statystki poszczególnych atrybutów, które są wynikiem funkcji summary.

knitr::kable(summary(df)) %>%
  kable_paper() %>%
  scroll_box(height = '100%') %>%  
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Battery.ID Battery.Formula Working.Ion Formula.Charge Formula.Discharge Max.Delta.Volume Average.Voltage Gravimetric.Capacity Volumetric.Capacity Gravimetric.Energy Volumetric.Energy Atomic.Fraction.Charge Atomic.Fraction.Discharge Stability.Charge Stability.Discharge Steps Max.Voltage.Step
Length:4351 Length:4351 Length:4351 Length:4351 Length:4351 Min. : 0.00002 Min. :-7.755 Min. : 5.176 Min. : 24.08 Min. :-583.5 Min. :-2208.1 Min. :0.00000 Min. :0.007407 Min. :0.00000 Min. :0.00000 Min. :1.000 Min. : 0.0000
Class :character Class :character Class :character Class :character Class :character 1st Qu.: 0.01747 1st Qu.: 2.226 1st Qu.: 88.108 1st Qu.: 311.62 1st Qu.: 211.7 1st Qu.: 821.6 1st Qu.:0.00000 1st Qu.:0.086957 1st Qu.:0.03301 1st Qu.:0.01952 1st Qu.:1.000 1st Qu.: 0.0000
Mode :character Mode :character Mode :character Mode :character Mode :character Median : 0.04203 Median : 3.301 Median : 130.691 Median : 507.03 Median : 401.8 Median : 1463.8 Median :0.00000 Median :0.142857 Median :0.07319 Median :0.04878 Median :1.000 Median : 0.0000
NA NA NA NA NA Mean : 0.37531 Mean : 3.083 Mean : 158.291 Mean : 610.62 Mean : 444.1 Mean : 1664.0 Mean :0.03986 Mean :0.159077 Mean :0.14257 Mean :0.12207 Mean :1.167 Mean : 0.1503
NA NA NA NA NA 3rd Qu.: 0.08595 3rd Qu.: 4.019 3rd Qu.: 187.600 3rd Qu.: 722.75 3rd Qu.: 614.4 3rd Qu.: 2252.3 3rd Qu.:0.04762 3rd Qu.:0.200000 3rd Qu.:0.13160 3rd Qu.:0.09299 3rd Qu.:1.000 3rd Qu.: 0.0000
NA NA NA NA NA Max. :293.19322 Max. :54.569 Max. :2557.627 Max. :7619.19 Max. :5926.9 Max. :18305.9 Max. :0.90909 Max. :0.993333 Max. :6.48710 Max. :6.27781 Max. :6.000 Max. :26.9607

Szczegółowa analiza atrybutów

W tej sekcji przedstawiona analiza kolejnych atrybutów w zbiorze danych - krótki opis obserwacji na podstawie tabel/wykresów.

Główny jon

Najczęściej w materiałach do baterii Li jest głównym jonem. Dalej po popularności są Ca, Mg, Zn i Na.

ion_counts <- as.data.frame(table(df$Working.Ion))
ion_counts <- arrange(ion_counts, desc(Freq))
knitr::kable(ion_counts,  col.names = c("Working Ion", "Count")) %>%  
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Working Ion Count
Li 2440
Ca 435
Mg 423
Zn 366
Na 309
K 107
Al 95
Y 93
Rb 50
Cs 33
Wzór chemiczny materiału baterii w stanie naładowanym

Materiał baterii w stanie naładowanym jest najczęściej przedstawiony w postaci tlenków tzn. związków chemicznych, zbudowanych z tlenu i innego pierwiastka chemicznego.

formula_charge_counts <- as.data.frame(table(df$Formula.Charge))
formula_charge_counts <- arrange(formula_charge_counts, desc(Freq))
datatable(colnames = c("Formula Charge", "Count"), formula_charge_counts)
Wzór chemiczny materiału baterii w stanie rozładowanym

Materiał baterii w stanie rozładowanym najcześciej zawiera Li, co może wynikać z tego, że on jest najpopularniejszym głównym jonem.

formula_discharge_counts <- as.data.frame(table(df$Formula.Discharge))
formula_discharge_counts <- arrange(formula_discharge_counts, desc(Freq))
datatable(formula_discharge_counts,colnames = c("Formula Discharge", "Count") )



Atrybuty ciągłe

Atrybuty ciągłe opisano za pomocą histogramów, gdzie ze źródłowych danych zostały usunięty outliery. Wykorzystano do tego IQR rule. W taki sposób usunięto dane powyżej i poniżej wyżnaczonych granic.


Zmiana objętości w % dla danego kroku napięcia oraz średnie napięcie

Większość baterii charakteryzuje się zmianą objętości w % dla danego kroku napięcia w przedziale [0, 0.05] i średnim napięciem w okolicach 3 V.

plot_1 <- ggplot2::ggplot(remove_outliers(df, "Max.Delta.Volume"), ggplot2::aes(Max.Delta.Volume, fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 0.01) + ggplot2::theme_bw() + scale_fill_brewer(palette = "Spectral") + 
  labs(title = 'Histogram atrybutu Max.Delta.Volume', x = 'Zmiana objętości w % dla danego kroku napięcia', y = 'Liczba baterii')
ggplotly(plot_1)
plot_2 <- ggplot2::ggplot(remove_outliers(df, "Average.Voltage"), ggplot2::aes(Average.Voltage, fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 1) + ggplot2::theme_bw() + scale_fill_brewer(palette = "Spectral") + 
  labs(title = 'Histogram atrybutu Average.Voltage', x = 'Średnie napięcie dla poszczególnego kroku napięcia', y = 'Liczba baterii')
ggplotly(plot_2)
Pojemność grawimetryczna i wolumetryczna

Większość baterii charakteryzuje się pojemnością grawimetryczną w przedziale [30, 200] i pojemnością wolumetryczną w przedziale [150,650]

plot_3 <- ggplot2::ggplot(remove_outliers(df, "Gravimetric.Capacity"), ggplot2::aes(Gravimetric.Capacity, fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 10) + ggplot2::theme_bw() + scale_fill_brewer(palette = "Spectral") + 
  labs(title = 'Histogram atrybutu Gravimetric.Capacity', x = 'Pojemność grawimetryczna mAh/g', y = 'Liczba baterii')
ggplotly(plot_3)
plot_4 <- ggplot2::ggplot(remove_outliers(df, "Volumetric.Capacity"), ggplot2::aes(Volumetric.Capacity,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 50) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
  labs(title = 'Histogram atrybutu Volumetric.Capacity', x = 'Pojemność wolumetryczna mAh/cm³', y = 'Liczba baterii')
ggplotly(plot_4)
Energia grawimetryczna i wolumetryczna

Większość baterii charakteryzuje się energią grawimetryczną w przedziale [0, 750] i energią wolumetryczną w przedziale [0, 2800]

plot_5 <- ggplot2::ggplot(remove_outliers(df, "Gravimetric.Energy"), ggplot2::aes(Gravimetric.Energy,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 50) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Gravimetric.Energy', x = 'Energia grawimetryczna Wh/kg', y = 'Liczba baterii')
ggplotly(plot_5)
plot_6 <- ggplot2::ggplot(remove_outliers(df, "Volumetric.Energy"), ggplot2::aes(Volumetric.Energy,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 200) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Volumetric.Energy', x = 'Energia wolumetryczna Wh/L', y = 'Liczba baterii')
ggplotly(plot_6)
Udział atomowy składników w stanie naładowanym i rozładowanym

Zdecydowana większość baterii ma udział atomowy składników w stanie naładowanym równy się 0. Z 4351 baterii 3220 baterii mają taką wartość atrybutu. Większość baterii charakteryzuje się udziałem atomowym składników w stanie rozładowanym w przedziale [0.045, 0.255]. W tym przedziale bardzo mała ilość baterii jest z udziałem atomowym składników w stanie rozładowanym w przedziale [0.24, 0.255]

plot_7 <- ggplot2::ggplot(remove_outliers(df, "Atomic.Fraction.Charge"), ggplot2::aes(Atomic.Fraction.Charge,  fill = Working.Ion)) + 
  ggplot2::geom_histogram() + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Atomic.Fraction.Charge', x = 'Udział atomowy składników w stanie naładowanym', y = 'Liczba baterii')
ggplotly(plot_7)
plot_8 <- ggplot2::ggplot(remove_outliers(df, "Atomic.Fraction.Discharge"), ggplot2::aes(Atomic.Fraction.Discharge,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 0.015) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Atomic.Fraction.Discharge', x = 'Udział atomowy składników w stanie rozładowanym', y = 'Liczba baterii')
ggplotly(plot_8)
Wskaźnik stabilności materiału w stanie naładowanym i rozładowanym

Większość baterii charakteryzuje się wskaźnikiem stabilności materiału w stanie naładowanym [0, 0.12] i w stanie rozładowanym w przedziale [0, 0.0975]

plot_9 <- ggplot2::ggplot(remove_outliers(df, "Stability.Charge"), ggplot2::aes(Stability.Charge,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 0.01) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Stability.Charge', x = 'Wskaźnik stabilności materiału w stanie naładowanym', y = 'Liczba baterii')
ggplotly(plot_9)
plot_10 <- ggplot2::ggplot(remove_outliers(df, "Stability.Discharge"), ggplot2::aes(x = Stability.Discharge,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 0.0075) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Stability.Discharge', x = 'Wskaźnik stabilności materiału w stanie rozładowanym', y = 'Liczba baterii')
ggplotly(plot_10)
Liczba odrębnych kroków napięcia od pełnego naładowania do rozładowania i maksymalna bezwzględna różnica między sąsiednimi krokami napięcia

W przypadku tych atrybutów outliery nie zostały usunięte.

Ponieważ atrybut liczba odrębnych kroków napięcia od pełnego naładowania do rozładowania zawiera dane całkowitoliczbowe od 1 do 6, to przedstawiono ile baterii ma określoną wartość wraz z histogramem aby wyświetlić też informacje o głównym jonie. Większość baterii potrzebuje 1 lub 2 kroki napięcia od naładowania do rozładowania.

ion_counts <- as.data.frame(table(df$Steps))
ion_counts <- arrange(ion_counts, desc(Freq))
knitr::kable(ion_counts,  col.names = c("Steps", "Count")) %>%  
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Steps Count
1 3752
2 500
3 77
4 16
5 5
6 1
plot_11 <- ggplot2::ggplot(df, ggplot2::aes(x = Steps,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 1) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Steps', x = 'Liczba odrębnych kroków napięcia od pełnego naładowania do rozładowania', y = 'Liczba baterii')
ggplotly(plot_11)

Dla atrybutu maksymalna bezwzględna różnica między sąsiednimi krokami napięcia przedstawiono histogram oraz tabele z ilością baterii, dla których wartość tego atrybutu zaokrąglano w górę do najbliższej liczby całkowitej. Z 4351 baterii 3752 baterii ma maksymalną bezwzględną różnica między sąsiednimi krokami napięcia równą 0. Istnieje również outlier z wartością 26.9606881

intervals <- ceiling(df$Max.Voltage.Step)
interval_counts_df <- as.data.frame(table(intervals))
colnames(interval_counts_df) <- c("ceiling", "count")
knitr::kable(interval_counts_df,  col.names = c("Max.Voltage.Step ceiling", "Count")) %>%  
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Max.Voltage.Step ceiling Count
0 3752
1 348
2 182
3 51
4 14
5 2
9 1
27 1
plot_12 <- ggplot2::ggplot(df, ggplot2::aes(x = Max.Voltage.Step,  fill = Working.Ion)) + 
  ggplot2::geom_histogram(binwidth = 1) + ggplot2::theme_bw()  + scale_fill_brewer(palette = "Spectral") +
    labs(title = 'Histogram atrybutu Max.Voltage.Step', x = 'Maksymalna bezwzględna różnica między sąsiednimi krokami napięcia', y = 'Liczba baterii')
ggplotly(plot_12)

Macierz korelacji

Korelacja pomiędzy wszystkimi atrybutami numerycznymi zbioru przedstawiona na macierzach korelacji. Zastosowano dwie metody - Piersona oraz Spearmana. Metoda Piersona pozwala na określenie, czy istnieje związek liniowy między dwoma zmiennymi. Natomiast metoda Spearmana służy do pomiaru monotonicznej relacji między dwiema zmiennymi. Może ona zapewnić dokładniejsze wyniki, ponieważ nie jest tak dotknięta wartościami ekstremalnymi, jak współczynnik korelacji Pearsona.

Na podstawie macierz można zauważyć, że pary atrybutów Gravimetric.Energy - Volumetric.Energy, Gravimetric.Capacity - Volumetric.Capacity, Average.Voltage - Gravimetric.Energy, Average.Voltage - Volumetric.Energy, Atomic.Fraction.Charge - Atomic.Fraction.Discharge, Gravimetric.Capacity - Atomic.Fraction.Discharge, Steps - Max.Voltage.Step są silnie skorelowane przy stosowaniu obu metod (współczynniki są większe od 0.5).

Współczynnik Spearmana pokazuje wyraźniej, że wraz ze wzrostem/spadkiem wartości atrybutu Steps tak samo wzrasta/spada wartość atrybutu Max.Voltage.Step, bo równa się 1. Podobnie jest z atrybutami Gravimetric.Capacity - Volumetric.Capacity oraz Gravimetric.Energy - Volumetric.Energy, co wynika z tego, że opisują takie same własności - energię oraz pojemność baterii.

df_numeric <- df %>% select(where(is.numeric))

correlation_matrix <- df_numeric %>% cor(use = "all.obs", method="pearson")
correlation_plot <- correlation_matrix %>% 
  ggcorrplot(type="lower", outline.col = "white", lab = TRUE, lab_size = 3, legend.title = "Pearson correlation", colors = c("#6D9EC1", "white", "#E46726")) +
  labs(x = 'Atrybut 1', y = 'Atrybut 2') + 
  theme_bw() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

ggplotly(correlation_plot) %>% layout( width = 850, 
    height = 530)
correlation_matrix_2 <- df_numeric %>% cor(use = "all.obs", method="spearman")
correlation_plot_2 <- correlation_matrix_2 %>% 
  ggcorrplot(type="lower", outline.col = "white", lab = TRUE, lab_size = 3, legend.title = "Spearman correlation", colors = c("#6D9EC1", "white", "#E46726")) +
  labs(x = 'Atrybut 1', y = 'Atrybut 2') + 
  theme_bw() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

ggplotly(correlation_plot_2) %>% layout( width = 850, 
    height = 530)


Trendy w materiałach dla baterii

Najbardziej popularnym głównym jonem w przedstawionym zbiorze jest Li . Takie baterii charakteryzują się dobrą pojemnością oraz stabilnością w stanie naładownym i rozładowanym. Dla baterii zarówno ważne jest aby nie miała efektu pamięci. To jest zjawisko powodujące utratę pojemności baterii. Przy powszechnym stosowaniu baterii wiekszej pojemności (np. dla samochodów elektrycznych) dużo rolę ma trwałość baterii. Ale te dane nie zostałe przedstawione w zbiorze danych.
Inne mniej popularnie, ale w podobnej ilości przedstawione w zbiorze są baterii z Ca , Mg , Na oraz Zn jak głównym jonem. Li, Na, Mg i Ca mają pewne podobieństwa chemiczne, ponieważ znajdują się w sąsiednich grupach układu okresowego. Te pierwiastki mają tendencję do oddawania elektronów w procesie jonizacji.
W przyszłości badania mogą koncentrować się na ulepszeniu baterii z Li, bo on dominuje na rynku dzisiaj. Badać jak można łagodzić degradacje, zwiększyć trwałości tzn. zwiększyć żywotność. Badania nad bateriami z Ca, Mg i Na jak głównym jonem jako alternatywa do Li będą kontynuowane, ale muszę skupiać się na komercyjnym zastosowaniu i skalowalności.

Artykuły:
1. Clare P. Grey and David S. Hall, Prospects for lithium-ion batteries and beyond—a 2030 vision. Nature Communications, https://www.nature.com/articles/s41467-020-19991-4.
2. Tsuyoshi Sasaki, Yoshio Ukyo, and Petr Novák, Memory Effect in a Lithium-ion Battery, https://www.tytlabs.co.jp/en/review/issue/files/453_057sasaki.pdf.

Przewidywanie dalszych własności baterii

Ponieważ pojemność w bateriach jest bardzo ważna, to spróbowano na podstawie wybranych atrybutów ze zbioru przewidzieć wartość atrybutu Gravimetric.Capacity.

Wybrane zostały atrybuty - Gravimetric.Energy, Atomic.Fraction.Discharge, Atomic.Fraction.Charge, Stability.Discharge, Max.Delta.Volume, Atomic.Fraction.Charge oraz Stability.Charge. Zbiór został podzielony na testowy (20%) i treningowy (80%).

data <- dplyr::select(df, Gravimetric.Capacity, Gravimetric.Energy, Atomic.Fraction.Discharge, Atomic.Fraction.Charge, Stability.Discharge, Max.Delta.Volume, Stability.Charge, Atomic.Fraction.Charge)

index <- createDataPartition(data$Gravimetric.Capacity, p = 0.8, list = FALSE)
trainData  <- data[index, ]
testData <- data[-index, ]

plot<- ggplot2::ggplot(alpha = 0.65) + 
  ggplot2::geom_density(aes(Gravimetric.Capacity, fill = "Zbior treningowy"), trainData) +
  ggplot2::geom_density(aes(Gravimetric.Capacity, fill = "Zbior testowy"), testData) +
  ggplot2::labs(x = "Gravimetric.Capacity", title = "Porównanie rozkładu zbiorów testowego i treningowego") + ggplot2::theme_bw()

ggplotly(plot)

Zostało użyte wzmocnienie gradientowe (Gradient Boosting) z parametrami - max.depth = 5 (maksymalna głębokość drzewa) oraz nrounds = 30 (maksymalna liczba iteracji). W wyniku otrzymano ponizszy model:

train_x <- as.matrix(trainData %>% select(-Gravimetric.Capacity))
train_y <- trainData$Gravimetric.Capacity
test_x <- as.matrix(testData %>% select(-Gravimetric.Capacity))
test_y <- testData$Gravimetric.Capacity

xgb_train = xgb.DMatrix(data = train_x, label = train_y)
xgb_test = xgb.DMatrix(data = test_x, label = test_y)

xgb_model <- xgb.train(data = xgb_train, max.depth = 5, nrounds = 300, verbose = 1)
xgb_model
## ##### xgb.Booster
## raw: 680.5 Kb 
## call:
##   xgb.train(data = xgb_train, nrounds = 300, verbose = 1, max.depth = 5)
## params (as set within xgb.train):
##   max_depth = "5", validate_parameters = "1"
## xgb.attributes:
##   niter
## callbacks:
##   cb.print.evaluation(period = print_every_n)
## # of features: 6 
## niter: 300
## nfeatures : 6

Została wyliczona ważność atrybutów przy podejmowaniu decyzji. Widać, że najważniejsze są atrybuty Atomic.Fraction.Discharge i Max.Delta.Volume.

importance_matrix <- xgb.importance(feature_names = colnames(xgb_train), model = xgb_model)
xgb.plot.importance(importance_matrix, left_margin = 12)

Dokonano porównania wartości rzeczywistych z tymi, które przewidział model i przedstawiono na wykresie. Z wykresu wynika, że model dobrze przewiduje wartości do 500, bo ich przedstawiono dużo w zbiorze, natomiast z większymi wartościami występują większe błędy.

xgb_preds <- predict(xgb_model, test_x)
xgb_preds <- as.data.frame(xgb_preds)
colnames(xgb_preds) <- c("Gravimetric.Capacity")


comparison <- data.frame(
  Actual = test_y,
  Predicted = xgb_preds$Gravimetric.Capacity
)

prediction_actual_plot <- ggplot(comparison, aes(x = Actual, y = Predicted)) +
  geom_point(alpha = 0.65, color = 'blue') +
  geom_abline(intercept = 0, slope = 1, color = 'red', linetype = "dashed") +
  labs(
    x = "Wartości rzeczywiste",
    y = "Predykcje",
    title = "Porównanie predykcji z rzeczywistymi wartościami"
  ) +
  theme_bw()

ggplotly(prediction_actual_plot)

Funckje oceny modelu - MAE - 26.179949 oraz RMSE - 56.9676459